home *** CD-ROM | disk | FTP | other *** search
- /*
- CDRemainingTrack - An XFCN to report remaining time on disc
- ©Apple Computer, Inc. 1988
- All Rights Reserved.
-
- 88/11/08 BL°B First Version
-
- To compile and link this file using Macintosh Programmer's Workshop,
-
- C -q2 CDRemainingTrack.c
- link -sn Main=CDRemainingTrack -sn STDIO=CDRemainingTrack ∂
- -sn INTENV=CDRemainingTrack -rt XFCN=42 ∂
- -m CDRemainingTrack CDRemainingTrack.c.o "{CLibraries}"CRuntime.o ∂
- "{CLibraries}"StdCLib.o ∂
- -o HyperCommands
-
- This link directive puts the XCMD in the file "HyperCommands".
- Substitute the name of the stack you want it in. To move XCMDs
- between stacks, use ResEdit. They can be in an individual stack,
- the Home stack, the HyperCard application, or the System File.
-
- */
-
- #include <cd.h>
-
- #define BUGSTART 79 /* last good track for TrackStart */
-
- /* local procedure definitions */
- OSErr DriverBugHack(short, long, long *, long *, long *);
-
- /************************************************************************
- *
- * Function: ReadQ
- *
- * Purpose: return track & time for current position
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: none
- *
- * Description: Simply call the driver with a READQ call. The track
- * number and absolute minute, second, block come back
- * in BCD. Convert them to decimal and return.
- *
- ************************************************************************/
- OSErr
- ReadQ(refNum, trackNo, minute, second, block)
- short refNum;
- long *trackNo;
- long *minute;
- long *second;
- long *block;
- {
- CDParam myPB;
- OSErr result;
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READQ;
-
- result = PBControl(&myPB, false);
-
- if (result == noErr)
- {
- *trackNo = (long) BCD2DECIMAL(myPB.csParam[1]);
- *minute = (long) BCD2DECIMAL(myPB.csParam[6]);
- *second = (long) BCD2DECIMAL(myPB.csParam[7]);
- *block = (long) BCD2DECIMAL(myPB.csParam[8]);
- }
- return result;
- }
-
-
- /************************************************************************
- *
- * Function: DiscTime
- *
- * Purpose: return total time on this disc
- *
- * Returns: OSErr
- * either noErr if everything was okay
- * or some parameter error from driver call.
- *
- * Side Effects:
- * fills in totalMinute, totalSecond, totalBlock
- *
- * Description:
- * call the driver ReadTOC call to get the appropriate
- * information. Ask for the "lead-out" time, which is
- * the end of the disc.
- *
- ************************************************************************/
- OSErr
- DiscTime(refNum, minute, second, block)
- short refNum;
- long *minute;
- long *second;
- long *block;
- {
- CDParam myPB;
- OSErr result;
-
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READTOC;
- myPB.csParam[0] = 0;
- myPB.csParam[1] = 2; /* request lead-out time */
-
- result = PBControl(&myPB, false);
-
- if (result == noErr)
- {
- *minute = (long) BCD2DECIMAL(myPB.csParam[0]);
- *second = (long) BCD2DECIMAL(myPB.csParam[1]);
- *block = (long) BCD2DECIMAL(myPB.csParam[2]);
- }
- return result;
- }
-
-
-
-
- /************************************************************************
- *
- * Function: TimeDiff
- *
- * Purpose: calculate difference between two times
- *
- * Returns: nothing
- *
- * Side Effects: fills rMinute, rSecond, rBlock
- *
- * Description: convert the absolute times designated by
- * {m1, s1, b1} and {m2, s2, b2} to absolute
- * blocks. Subtract the second time from the
- * first. Convert the result back to {m, s, f}
- * format.
- *
- ************************************************************************/
- void
- TimeDiff(rMinute, rSecond, rBlock, m1, s1, b1, m2, s2, b2)
- long *rMinute;
- long *rSecond;
- long *rBlock;
- long m1, s1, b1, m2, s2, b2;
- {
- long time1, time2;
- long minute, second, block;
-
- time1 = b1 + (s1 * BLOCKSEC) + (m1 * BLOCKMIN);
- time2 = b2 + (s2 * BLOCKSEC) + (m2 * BLOCKMIN);
-
- time1 = time1 - time2;
-
- minute = time1 / BLOCKMIN;
- time1 = time1 - (minute * BLOCKMIN);
-
- second = time1 / BLOCKSEC;
- block = time1 - (second * BLOCKSEC);
-
- *rMinute = minute;
- *rSecond = second;
- *rBlock = block;
- }
-
- /************************************************************************
- *
- * Function: TrackStart
- *
- * Purpose: return start of specified track
- *
- * Returns: OSErr. Probably either
- * noErr everything's hunky-dory!
- * paramErr you messed up the call somehow.
- *
- * Side Effects: modifies "minute", "second", and "block" to indicate
- * start of current track.
- *
- * Description: Simply call the driver and return the values
- * byte that the driver gives us. See the developer's
- * guide for information about the READTOC command.
- *
- ************************************************************************/
- OSErr
- TrackStart(refNum, trackNo, minute, second, block)
- short refNum;
- long trackNo;
- long *minute;
- long *second;
- long *block;
- {
- CDPlay3Param myPB;
- OSErr result;
- char track[4];
-
- if (trackNo > BUGSTART)
- result = DriverBugHack(refNum, trackNo, minute, second, block);
- else
- {
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READTOC;
- myPB.readType = 3;
- myPB.bufAddr = track;
- myPB.bufferLength = 4;
- myPB.track = DECIMAL2BCD(trackNo);
-
- result = PBControl(&myPB, false);
- *minute = (long) BCD2DECIMAL(track[1]);
- *second = (long) BCD2DECIMAL(track[2]);
- *block = (long) BCD2DECIMAL(track[3]);
- }
- return result;
- }
-
- /************************************************************************
- *
- * Function: DriverBugHack
- *
- * Purpose: read TOC to get around driver bug
- *
- * Returns: OSErr
- * usually 0, but can be negative if driver returns
- * an error
- *
- * Side Effects: fills minute, second, and block with the correct
- * values for the specified track.
- *
- * Description: There is a bug in the Apple CD-ROM driver 2.0
- * which makes it return incorrect information for
- * a track greater than 79 if you ask for it alone.
- * We ask for tracks 79 through the specified track.
- * This should get around the bug.
- *
- ************************************************************************/
- OSErr
- DriverBugHack(refNum, trackNo, minute, second, block)
- short refNum;
- long trackNo;
- long *minute;
- long *second;
- long *block;
- {
- CDPlay3Param myPB;
- OSErr result;
- char *track;
- short trackSize;
- short i;
-
- trackSize = (short)trackNo * 4; /* 4 bytes per track in call */
- track = NewPtr(trackSize);
- if (track == nil)
- result = MemError();
- else
- {
- myPB.ioCompletion = 0;
- myPB.ioNamePtr = (char *) 0;
- myPB.ioVRefNum = 1;
- myPB.ioCRefNum = refNum;
- myPB.csCode = READTOC;
- myPB.readType = BUFADDR;
- myPB.bufAddr = track;
- myPB.bufferLength = trackSize;
- myPB.track = 0x01; /* BCD */
-
- result = PBControl(&myPB, false);
- i = (trackNo - 1) * 4;
- *minute = (long) BCD2DECIMAL(track[i+1]);
- *second = (long) BCD2DECIMAL(track[i+2]);
- *block = (long) BCD2DECIMAL(track[i+3]);
- DisposPtr(track);
- }
- return result;
- }
-